import json
import logging

from django.http import JsonResponse
from rest_framework.views import APIView

from menu.models import SysMenu, SysMenuSerializer, SysRoleMenu
from utils.check_permission import check_permission

logger = logging.getLogger()
# 修改权限
logger.setLevel(logging.INFO)

class TreeListView(APIView):
    """角色菜单树"""

    @check_permission(perms_list=['system:menu:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def build_tree_menu(self, sys_menu_list):
        result_menu_list: list[SysMenu] = list()
        for menu in sys_menu_list:
            try:
                menu.create_time = menu.create_time.strftime('%Y-%m-%d %H:%M:%S')
                menu.update_time = menu.update_time.strftime('%Y-%m-%d %H:%M:%S')
            except AttributeError as e:
                logger.error(str(e))
            # 寻找子节点
            for item in sys_menu_list:
                if item.parent_id == menu.id:
                    if not hasattr(menu, "children"):
                        menu.children = list()
                    menu.children.append(item)
            # 判断父节点，添加到集合
            if menu.parent_id == 0:
                result_menu_list.append(menu)
        return result_menu_list

    def get(self, request):
        menu_queryset = SysMenu.objects.order_by('order_num')
        # 构造菜单树
        sys_ment_list: list[SysMenu] = self.build_tree_menu(menu_queryset)
        try:
            serializer_menu_list: list[SysMenuSerializer] = list()
            for sys_menu in sys_ment_list:
                serializer_menu_list.append(SysMenuSerializer(sys_menu).data)
        except Exception as e:
            logging.error(e)
            return JsonResponse({"code": 500, "msg": "角色菜单树构造失败"})
        return JsonResponse({"code": 200, "msg": serializer_menu_list})


class SaveView(APIView):
    """添加和修改菜单"""

    @check_permission(perms_list=['system:menu:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def post(self, request):
        data = json.loads(request.body.decode("utf-8"))
        try:
            if data['id'] == -1:  # 添加
                obj_sys_menu = SysMenu(name=data['name'], icon=data['icon'], parent_id=data['parent_id'],
                                       order_num=data['order_num'], path=data['path'], component=data['component'],
                                       menu_type=data['menu_type'], perms=data['perms'], remark=data['remark'])
                obj_sys_menu.save()
            else:  # 修改
                obj_sys_menu = SysMenu(id=data['id'], name=data['name'], icon=data['icon'], parent_id=data['parent_id'],
                                       order_num=data['order_num'], path=data['path'], component=data['component'],
                                       menu_type=data['menu_type'], perms=data['perms'], remark=data['remark'],
                                       create_time=data['create_time'])
                obj_sys_menu.save()
        except Exception as e:
            logging.error(e)
            return JsonResponse({"code": 500, "msg": "操作失败，请联系管理员"})
        return JsonResponse({"code": 200})


class ActionView(APIView):
    """菜单基本操作"""

    @check_permission(perms_list=['system:menu:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get(self, request):
        """查询新增的menu数据"""
        menu_id = request.GET.get("id")
        menu_obj = SysMenu.objects.get(id=menu_id)
        return JsonResponse({"code": 200, "msg": SysMenuSerializer(menu_obj).data})

    def delete(self, request):
        """删除menu数据"""
        menu_id = json.loads(request.body.decode("utf-8"))
        try:
            if SysMenu.objects.filter(parent_id=menu_id).count() > 0:
                return JsonResponse({"code": 500, "msg": "请先删除子菜单"})
            else:
                SysRoleMenu.objects.filter(menu_id=menu_id).delete()
                SysMenu.objects.get(id=menu_id).delete()
        except Exception as e:
            logging.error(e)
            return JsonResponse({"code": 500, "msg": "操作失败，请联系管理员"})
        return JsonResponse({"code": 200})
